package com.mjk.manager.workflow.parser.sql.read.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.mjk.common.core.jdbc.service.plus.idbservice.BeeDBService;
import com.mjk.common.core.jdbc.service.plus.wrap.BeeQueryWrapper;
import com.mjk.common.tools.logger.BizLogger;
import com.mjk.common.tools.springextend.BeeSpringBean;
import com.mjk.manager.workflow.parser.constant.ReadType;
import com.mjk.manager.workflow.parser.constant.SqlReadConstant;
import com.mjk.manager.workflow.parser.sql.exception.ELSQLException;
import com.mjk.manager.workflow.parser.sql.model.ScriptModel;
import com.mjk.manager.workflow.parser.sql.read.AbstractSqlRead;
import com.mjk.manager.workflow.parser.sql.vo.SQLParserVO;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import com.yomahub.liteflow.enums.ScriptTypeEnum;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 脚本读取
 *
 * @author tangkc
 * @author houxinyu
 * @since 2.11.1
 */
public class ScriptRead extends AbstractSqlRead {

    public ScriptRead(SQLParserVO config) {
        super(config);
    }
    @Override
    public Map<String/*规则唯一键*/, String/*规则内容*/> read() {
        // 如果不需要读取直接返回
        if (!needRead()) {
            return new HashMap<>();
        }

        Map<String/*规则唯一键*/, String/*规则*/> result = new HashMap<>();
        try {
            BeeDBService baseDBService = BeeSpringBean.getBean(BeeDBService.class);
            BeeQueryWrapper wrapper = new BeeQueryWrapper(new ScriptModel());
            wrapper.eq(ScriptModel::getApplicationName, this.config.getApplicationName()).eq(ScriptModel::getEnable, "1");
            List<ScriptModel> scripts = Objects.requireNonNull(baseDBService).findManyByWrapper(wrapper);
            for (ScriptModel script : scripts) {
                result.put(buildXmlElementUniqueKey(script), script.getScriptData());
            }
        } catch (Exception e) {
            BizLogger.error(" table 'script' read error");
        }
        return result;
    }

    public String buildXmlElementUniqueKey(ScriptModel script)  {
        NodeTypeEnum nodeTypeEnum = NodeTypeEnum.getEnumByCode(script.getScriptType());
        if (Objects.isNull(nodeTypeEnum)) {
            throw new ELSQLException(StrUtil.format("Invalid type value[{}]", script.getScriptType()));
        }

        if (!nodeTypeEnum.isScript()) {
            throw new ELSQLException(StrUtil.format("The type value[{}] is not a script type", script.getScriptType()));
        }

        if (withLanguage() && !ScriptTypeEnum.checkScriptType(script.getLanguage())) {
            throw new ELSQLException(StrUtil.format("The language value[{}] is invalid", script.getLanguage()));
        }
        List<String> keys = CollUtil.newArrayList(script.getScriptId(), script.getScriptType(), script.getScriptName());
        if (StrUtil.isNotBlank( script.getLanguage())) {
            keys.add( script.getLanguage());
        }
        return StrUtil.join(StrUtil.COLON, keys);
    }

    @Override
    public boolean needRead() {
        if (StrUtil.isBlank(super.config.getScriptTableName())) {
            return false;
        }

        String sqlCmd = StrUtil.format(
                SqlReadConstant.SCRIPT_SQL_CHECK_PATTERN,
                super.config.getScriptTableName()
        );
        return true;
    }

    @Override
    public ReadType type() {
        return ReadType.SCRIPT;
    }

    /**
     * 脚本是否带语言
     */
    private boolean withLanguage() {
        return StrUtil.isNotBlank(super.config.getScriptLanguageField());
    }
}
